package com.digiwin.dap.middleware.auth;


import com.digiwin.dap.middleware.exception.BusinessException;
import com.digiwin.dap.middleware.util.JwtUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;

/**
 * @author chenxsa
 */
public abstract class AbstractTokenService<T>  {

    @Autowired
    ObjectMapper objectMapper;

    /**
     * 是否过期
     * @return
     */
    protected  boolean isExpire(){
        return  true;
    }

    /**
     * 是否校验数据
     * @return
     */
    protected  boolean isVerifyData(){
        return  true;
    }

    /**
     * 验证数据是否合法
     * @param data 数据
     * @return 成功返回true，失败返回false
     */
    public  abstract boolean validateData(T data) ;

    /**
     * 根据访问请求获取token
     *
     * @param data 数据
     * @return 生成的token字符串
     */

    public String getToken(T data) {
        if (data==null) {
            throw new IllegalArgumentException("data 不能为null");
        }
        if (!validateData(data)){
             return "";
        }

        String json;
        try {
            json = objectMapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
             throw new RuntimeException(e);
        }
        return JwtUtils.sign(json,getIssuer(),this.isExpire());
    }
    /**
     * 根据token换取请求
     * @param token token字符串
     * @return  json解析后的数据
     */
    public T getData(String token){
        try {
            if (this.isVerifyData()) {
                return (T) objectMapper.readValue(JwtUtils.getData(token, getIssuer()), getType());
            }
            else{
                return (T) objectMapper.readValue(JwtUtils.getDataWithoutVerify(token, getIssuer()), getType());
            }
        } catch (IOException e) {
            throw  new BusinessException(e);
        }
    }
    /**
     * 获取数据类型
     * @return json对应的数据类
     */
    protected  abstract  Class<?> getType();
    /**
     * 获取签名方
     * @return 签名方
     */
    protected  abstract  String getIssuer();

    /**
     * 根据token换取请求
     *
     * @param token
     * @return 验证
     */
    public boolean validate(String token) {
       return JwtUtils.verify(token,getIssuer());
    }
}
